package hch.redesFerroviarias;

import hch.utils.ControladorDeSalida;
import hch.utils.Sentido;

import java.util.List;
import java.util.Random;
import java.util.concurrent.locks.Condition;


public class Tren extends Thread {
	private int id;
	private int nroEstacion;
	private int capacidadMax;
	private int capacidadActual;
	private int cantidadQueBajan;
	private Sentido sentido;
	private Condition esperar;
	private RedFerroviaria red;
	private List<Estacion> estaciones;
	
	public Tren(int id, Sentido sentido, int numeroEstacion, int capMax, RedFerroviaria red){
		this.id      = id;
		this.sentido = sentido;
		this.nroEstacion  = numeroEstacion;
		this.capacidadMax = capMax;
		this.capacidadActual = 0;
		this.cantidadQueBajan = 0;
		this.red = red;
		this.estaciones = red.getEstaciones();
		this.esperar = RedFerroviaria1.LOCK.newCondition();
		this.initPermisosEnEstaciones();
		this.initContadores();
	}
	
	private void initPermisosEnEstaciones(){
		for (Estacion estacion : this.estaciones) {
			estacion.putPermiso(this.id);
		}
	}
	
	private void initContadores(){
		for (Estacion estacion : this.estaciones) {
			estacion.putContador(this.id);
		}
	}
	
	//*************//
	//** METHODS **//
	//*************//
	public synchronized void agregarPasajero() {
		this.capacidadActual ++;
	}
	
	public synchronized void removerPasajero(){
		this.capacidadActual --;
		this.cantidadQueBajan --;
	}
	
	public void setProximaEstacion(){
		if(this.sentido == Sentido.DERECHA){
			if(this.nroEstacion == estaciones.size())
				this.nroEstacion = 1;
			else
				this.nroEstacion++;
		}else{
			if(this.nroEstacion == 1)
				this.nroEstacion = estaciones.size();
			else 
				this.nroEstacion--;
		}
	}
	
	public boolean estaLleno(){
		return this.capacidadActual == this.capacidadMax;
	}
		
	public void run() {
		Estacion estacion;
		while (true) {
			try {
				estacion = this.estaciones.get(this.nroEstacion - 1);
				estacion.removeTren(this);
				this.setProximaEstacion();
				estacion = this.estaciones.get(this.nroEstacion - 1);
				Thread.sleep(new Random().nextInt(3000)); //Viaje
				estacion.addTrenEnEspera(this);
				estacion.obetenerAnden();
				estacion.removeTrenEnEspera(this);
				estacion.addTren(this);
				RedFerroviaria1.LOCK.lock();
				this.red.imprimirEstado();
				this.cantidadQueBajan = estacion.getCantidadQueBajan(this.id);
				estacion.getPuedenBajar(this.id).signalAll();
				estacion.getPuedenSubir().signalAll();
				new ControladorDeSalida(this).start();
				this.esperar.await();
				estacion.resetearContador(this.id);
				this.red.imprimirEstado();
				RedFerroviaria1.LOCK.unlock();
				estacion.dejarAnden();
			} catch (InterruptedException e) {}
		}
	}
	
	//**************//
	//** ACCESORS **//
	//**************//
	public int getNroEstacion() {
		return nroEstacion;
	}
	
	public int getCapacidadMax() {
		return capacidadMax;
	}
	
	public int getCapacidadActual() {
		return capacidadActual;
	}
	
	public Sentido getSentido() {
		return sentido;
	}
	
	public int getCantidadQueBajan() {
		return cantidadQueBajan;
	}
	
	public int getTId() {
		return this.id;
	}
	
	public Condition getEsperar() {
		return esperar;
	}
	
	public RedFerroviaria getRed() {
		return red;
	}

	@Override
	public String toString() {
		return "T"+id+"("+this.capacidadActual+"/"+this.capacidadMax+")";
	}
}
